package ks.client.game.wordsteal;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.StringTokenizer;

import ks.client.interfaces.IGameInterface;
import wordsteal.entities.Board;
import wordsteal.entities.Cell;
import wordsteal.entities.Rack;
import wordsteal.entities.Tile;
import wordsteal.interfaces.IWordstealApp;
import wordsteal.util.BoardLocation;

/**
 * MakeTurnController is launched when a turn is received by a client.
 * <p>
 * Not responsible for emitting any requests to server 
 * 
 * @author Dan and George Heineman
 */
public class MakeTurnController extends CommonMoveController {
	
	/** 
	 * Construct controller
	 * @param mainFrame MainFrame allows ability to set and retrieve entity information
	 */
	public MakeTurnController(IWordstealApp mainFrame) {
		super(mainFrame);
	}
	
	/**
	 * Launches the controller that handles the playing of a move.
	 * Best way to do this is to 'simulate' the playing of tiles
	 * that must be valid onto the board, and then requesting
	 * the SubmitWordController to do its part. 
	 * 
	 * Sample move string:
	 * (6/9)=E,(6/8)=O,(6/7)=H,(6/6)=S
	 * 
	 * @param callback 
	 * @param moveString 
	 * @param playerID 
	 */
	public boolean process(WordstealGameInformation info, IGameInterface callback, String playerID, String moveString){
		
		// build up hashtable <Point,Character>.
		Hashtable<java.awt.Point,String> tiles = new Hashtable<java.awt.Point,String>();
		try {
			StringTokenizer st = new StringTokenizer(moveString, "(/,)=");
			while (st.hasMoreTokens()) {
				int row = Integer.valueOf(st.nextToken());
				int col = Integer.valueOf(st.nextToken());
				String ch = st.nextToken();
				tiles.put(new java.awt.Point(row,col), ch);
			}
		} catch (Exception e) {
			System.err.println("Unable to interpret move string:" + moveString);
			return false;
		}
		
		// Place all tiles on the board
		
		Rack rack = this.mf.getGame().getRack();
		Board board = this.mf.getGame().getBoard();
		ArrayList<Tile> allTiles = rack.getTiles();
		for (java.awt.Point p : tiles.keySet()) {
			String ch = tiles.get(p);
			for (int i = 0; i < allTiles.size(); i++) {
				Tile t = allTiles.get(i);
				if (t.letter.equals(ch)) {
					rack.removeTile(t);
					Cell cell = board.getCell(p.x, p.y);
					cell.setTile(t);
					break;
				}
			}
		}
		
		// Holds the list of word strings created on the board
		ArrayList<String> words = new ArrayList<String>();
		// Holds the list of cells where new words are located
		ArrayList<ArrayList<Cell>> wordCells = new ArrayList<ArrayList<Cell>>(); 
    	// Holds the cells containing tiles played this turn
    	Hashtable<BoardLocation, Cell> playedTileCells = this.mf.getGame().getBoard().getNewTiles();
    	
    	wordCells = board.extractAdjacentWordCells(playedTileCells);
		words = board.formWordsFromCells(wordCells);
		
		boolean complete = finishSubmitWord(playerID, words, wordCells, playedTileCells);
				
		this.mf.updateGUI();
		
		if (complete) {
			// disable future play
			info.stop();
			return true;
		} else {
			info.resetTimer();

			return true;
		}
	}


}
